cmake_minimum_required(VERSION 3.10)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O2")

if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
    message(FATAL_ERROR "Prevented in-tree built. Please create a build directory outside of the SDL source code and call cmake from there")
endif()

project(
    SDLEngine
    DESCRIPTION "a small engine based on SDL2 in C++"
    LANGUAGES CXX
    VERSION 0.1.0
)

set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_EXTENSIONS OFF)

#########################
# enable/disable options
#########################

option(sdlengine-with-tests
       "enable/disable unit tests for sdlengine and it's components"
       ON)

option(sdlengine-with-demos
       "enable/disable sdlengine's demo"
       ON)

option(sdlengine-with-tools
       "enabld/disable build sdlengine's tools"
       ON)

if (COMPILE_ON_ANDROID)
    set(sdlengine-with-tests OFF)
    set(sdlengine-with-demos OFF)
    set(sdlengine-with-tools OFF)
endif()

#### prev declare the target ####

add_library(${PROJECT_NAME} STATIC)

#########################
# check language support
#########################

include(CheckCXXSourceRuns)

set(_test_cpp17_filesystem
"
#include <filesystem>
using namespace std;
namespace fs = std::filesystem;

int main(void) {
    fs::path path(\"./test/path\");
    fs::directory_entry entry(path);
}
")

if (COMPILE_ON_ANDROID)
    set(_cpp17_fs_runs FALSE PARENT_SCOPE)
else()
    check_cxx_source_runs("${_test_cpp17_filesystem}" _cpp17_fs_runs)
endif()

set(CPP17FILESYSTEM_VALID FALSE)
if (_cpp17_fs_runs)
    set(CPP17FILESYSTEM_VALID TRUE)
else()
    message(WARNING "your c++ compiler don't support filesystem(C++ 17 feature)")
endif()


#########################
# configure file
#########################
configure_file(
    platform/platform.hpp.in
    ${CMAKE_CURRENT_SOURCE_DIR}/include/platform.hpp
    @ONLY
)

#########################
# build SDLEngine library
#########################

set(SDL2_DEP)
set(SDL2_IMAGE_DEP)
set(SDL2_TTF_DEP)

if (COMPILE_ON_ANDROID)
    find_library(SDL2 SDL2)
    find_library(SDL2_image SDL2_image)
    find_library(SDL2_ttf SDL2_ttf)

    add_library(SDL2_DEP ALIAS SDL2)
    add_library(SDL2_IMAGE_DEP ALIAS SDL2_image)
    add_library(SDL2_TTF_DEP ALIAS SDL2_ttf)
else()
    # use pkg-config to find SDL2
    find_package(PkgConfig REQUIRED)
    pkg_check_modules(SDL2 REQUIRED IMPORTED_TARGET sdl2)
    pkg_check_modules(SDL2_image REQUIRED IMPORTED_TARGET sdl2_image)
    pkg_check_modules(SDL2_ttf REQUIRED IMPORTED_TARGET sdl2_ttf)

    add_library(SDL2_DEP ALIAS PkgConfig::SDL2)
    add_library(SDL2_IMAGE_DEP ALIAS PkgConfig::SDL2_image)
    add_library(SDL2_TTF_DEP ALIAS PkgConfig::SDL2_ttf)
endif()

aux_source_directory(src SRC)

target_sources(
    ${PROJECT_NAME}
    PRIVATE ${SRC}
)

target_include_directories(
    ${PROJECT_NAME}
    PUBLIC include external
)

target_link_libraries(
    ${PROJECT_NAME}
    # PUBLIC PkgConfig::SDL2 PkgConfig::SDL2_image PkgConfig::SDL2_ttf
    PUBLIC SDL2_DEP SDL2_IMAGE_DEP SDL2_TTF_DEP
)

target_compile_options(
    ${PROJECT_NAME}
    PUBLIC -Wextra -Wshadow -Wcast-qual -Winline -Wunreachable-code -Wcast-align
           -Wundef -Wredundant-decls -Waddress -Warray-bounds -Wformat
           -Wswitch -Wtrigraphs -Wuninitialized -Wunused-function -Wunused-label
           -Wunused-value -Wunused-variable -Wpedantic -Wimplicit-fallthrough
)

if (NOT COMPILE_ON_ANDROID)
    target_precompile_headers(
        ${PROJECT_NAME}
        PUBLIC include/pch.hpp
    )
endif()

##########components###########
option(sdlengine-component-benchmark
       "enable/disable benchmark component"
       ON)
option(sdlengine-component-bresenham
       "enable/disable bresenham component"
       ON)
option(sdlengine-component-ecs
       "enable/disable ecs component"
       ON)
option(sdlengine-component-luascript
       "enable/disable luascript component"
       ON)
option(sdlengine-component-objectpool
       "enable/disable object pool component"
       ON)

if (COMPILE_ON_ANDROID)
    set(sdlengine-component-benchmark OFF)
    set(sdlengine-component-bresenham OFF)
    set(sdlengine-component-ecs OFF)
    set(sdlengine-component-luascript OFF)
    set(sdlengine-component-objectpool OFF)
endif()

if (sdlengine-component-benchmark)
    include(${CMAKE_CURRENT_SOURCE_DIR}/components/benchmark/benchmark.cmake)
    target_link_libraries(${PROJECT_NAME}
                          PUBLIC Component::Benchmark)
endif()

if (sdlengine-component-bresenham)
    include(${CMAKE_CURRENT_SOURCE_DIR}/components/bresenham/bresenham.cmake)
    target_link_libraries(${PROJECT_NAME}
                          PUBLIC Component::Bresenham)
endif()

if (sdlengine-component-ecs)
    include(${CMAKE_CURRENT_SOURCE_DIR}/components/ecs/ecs.cmake)
    target_link_libraries(${PROJECT_NAME}
                          PUBLIC Component::ECS)
endif()

if (sdlengine-component-luascript)
    include(${CMAKE_CURRENT_SOURCE_DIR}/components/lua_script/lua_scripe.cmake)
    target_link_libraries(${PROJECT_NAME}
                          PUBLIC Component::LuaScript)
endif()

if (sdlengine-component-objectpool)
    include(${CMAKE_CURRENT_SOURCE_DIR}/components/object_pool/object_pool.cmake)
    target_link_libraries(${PROJECT_NAME}
                          PUBLIC Component::ObjectPool)
endif()


#########################
# build SDLEngine Demo
#########################

if (sdlengine-with-demos)
    add_subdirectory(sandbox)
endif()


#########################
# build SDLEngine tests
#########################

if (sdlengine-with-tests)
    if (${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME})
        include(CTest)
    endif()

    add_subdirectory(tests)
endif()


#########################
# build SDLEngine tools
#########################

if (sdlengine-with-tools)
    add_subdirectory(tools)
endif()
